﻿using System;
using System.Linq;
using System.Linq.Expressions;
using MySql.Simple.Mapper.Structures;

namespace MySql.Simple.Mapper.Linq.Query
{
    /// <summary>
    /// MySQL LINQ Query Provider
    /// </summary>
    public class MySqlQueryProvider : IQueryProvider 
    {    
        public IQueryable CreateQuery(Expression expression)
        {
            var elementType = expression.Type.GetInnerElementType();

            try
            {
                return (IQueryable)Activator.CreateInstance(typeof(Query<>).MakeGenericType(elementType), new object[] { this, expression });
            }
            catch (System.Reflection.TargetInvocationException tie)
            {
                throw tie.InnerException;
            }
        }

        public IQueryable<T> CreateQuery<T>(Expression expression) 
        {
            return new Query<T>(this, expression);
        }

        public object Execute(Expression expression)
        {
            var context = new MySqlQueryContext<object>();

            var result = context.Execute(expression, false, Connection.Create());

            GeneratedSql = context.GeneratedSql;

            return result;
        }

        public T Execute<T>(Expression expression) 
        {
            var isEnumerable = (typeof(T).Name == "IEnumerable`1");

            var context = new MySqlQueryContext<T>();

            var result = (T)context.Execute(expression, isEnumerable, Connection.Create());

            GeneratedSql = context.GeneratedSql;

            return result;
        }

        public string GeneratedSql { get; private set; }
    }
}